﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using blacksoft.Models;
using blacksoft.Constantes;

namespace blacksoft.Controllers
{
    public class PersonalController : Controller
    {
        private inf245travelbusEntities db = new inf245travelbusEntities();
        //Declaración de constantes internas
        //Estados posibles
        private class Estado
        {
            public string valor { get; set; }
            public string nombre { get; set; }

            public Estado(string valor, string nombre)
            {
                this.valor = valor;
                this.nombre = nombre;
            }
        }
        private List<Estado> estados = new List<Estado> { new Estado("AC", "Activo"), new Estado("IN", "Inactivo") };
        private List<Estado> estados_full = new List<Estado> { new Estado("AC", "Activo"), new Estado("IN", "Inactivo"), new Estado("AN", "Anulado") };
        //Cadena para anulación
        private Estado est_anulado = new Estado("AN", "Anulado");
        //Tipos de persona
        private class TipoPersona
        {
            public int valor { get; set; }
            public string nombre { get; set; }
            public TipoPersona(int valor, string nombre)
            {
                this.valor = valor;
                this.nombre = nombre;
            }
        }
        private List<TipoPersona> tipos_persona = new List<TipoPersona> { new TipoPersona(1, "Proveedor"), new TipoPersona(2, "Personal"), new TipoPersona(3, "Cliente Regular"), new TipoPersona(4, "Cliente Frecuente") };
        private TipoPersona tipo_persona_personal = new TipoPersona(2, "Personal");

        //Cargos de la empresa
        private string[] cargos = { "Administrador/a", "Chofer", "Gerente", "Mecánica/o", "Terramoza/o", "Vendedora/o" };

        // GET: /Personal/
        public ActionResult Index(string search_dni, string search_nombre, string search_cargo, string search_estado, string search_terminal)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            var persona = db.Persona.Include(p => p.Terminal).Include(p => p.UnidadVenta);
            //Sólo personal (tipo 2)
            persona = persona.Where(p => p.TipoPersona == 2);

            //Si no es global
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL))
            {
                //Select de todas las unidades de la terminal
                int id_terminal = (int)Session["IDTerminal"];
                persona = persona.Where(p => p.IDTerminal == id_terminal);
            }

            //DNI
            var dni_lst = new List<string>();
            var dni_qry = from p in persona
                          where p.Estado != est_anulado.valor
                          orderby p.DNI
                          select p.DNI;
            dni_lst.AddRange(dni_qry.Distinct());
            ViewBag.search_dni = new SelectList(dni_lst);

            if (!string.IsNullOrEmpty(search_dni))
            {
                persona = persona.Where(p => p.DNI == search_dni);
            }

            //Nombres
            if (!string.IsNullOrEmpty(search_nombre))
            {
                persona = persona.Where(p => p.Nombre.Contains(search_nombre) || p.ApellidoPaterno.Contains(search_nombre) || p.ApellidoMaterno.Contains(search_nombre));
            }

            //Cargos
            ViewBag.search_cargo = new SelectList(cargos);

            if (!string.IsNullOrEmpty(search_cargo))
            {
                persona = persona.Where(p => p.CargoPersonal == search_cargo);
            }

            //Estados
            ViewBag.search_estado = new SelectList(estados_full, "valor", "nombre");
            ViewBag.EstadoAC = estados_full.Find(e => e.valor == "AC").nombre;
            ViewBag.EstadoIN = estados_full.Find(e => e.valor == "IN").nombre;
            ViewBag.EstadoAN = estados_full.Find(e => e.valor == "AN").nombre;

            if (!string.IsNullOrEmpty(search_estado))
            {
                persona = persona.Where(p => p.Estado == search_estado);
            }

            //Terminal
            var term_lst = new List<string>();
            var term_qry = from t in db.UnidadTransporte
                           orderby t.Terminal.Nombre
                           select t.Terminal.Nombre;
            term_lst.AddRange(term_qry.Distinct());
            ViewBag.search_terminal = new SelectList(term_lst);

            if (!string.IsNullOrEmpty(search_terminal))
            {
                persona = persona.Where(p => p.Terminal.Nombre == search_terminal);
            }

            if(search_estado != est_anulado.valor)
            {
                persona = persona.Where(p => p.Estado != est_anulado.valor);
            }
            
            return View(persona.ToList());
        }

        // GET: /Personal/Details/5
        public ActionResult Details(int? id)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            if (id == null)
            {
                return View("Error404");
            }
            try
            {
                Persona persona = db.Persona.Find(id);
                if (persona == null)
                {
                    return View("Error404");
                }

                //No permitir acceso a info de otras terminales
                if (!global && persona.IDTerminal != (int)Session["IDTerminal"])
                {
                    TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                    return RedirectToAction("Index", "ModuloAdmin");
                }

                try
                {
                    ViewBag.Estado = estados.Find(e => e.valor == persona.Estado).nombre;
                }
                catch
                {
                    TempData["details_failure"] = "no se encontró el estado del personal";
                }

                return View(persona);
            }
            catch
            {
                TempData["details_failure"] = "no se encontró el personal";
                return RedirectToAction("Index");
            }
        }

        // GET: /Personal/Create
        public ActionResult Create()
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            ViewBag.Estado = new SelectList(estados, "valor", "nombre", estados[0].valor);

            //Controlar global vs. local-----------------------------------------------------------
            if (!global)
            {
                //Usuario local
                ViewBag.IDTerminal = (int)Session["IDTerminal"];
            }
            else
            {
                //Usuario global
                string activo = estados[0].valor;
                var terminales = from t in db.Terminal
                                 where t.Estado == activo
                                 select t;
                int id_terminal = (int)Session["IDTerminal"];
                ViewBag.IDTerminal = new SelectList(terminales, "IDTerminal", "Nombre", id_terminal);
                var unidades_venta = from u in db.UnidadVenta
                                     where u.Estado == activo
                                     select u;
                ViewBag.IDUnidadVenta = new SelectList(unidades_venta, "IDUnidadVenta", "Nombre");
            }
            //-------------------------------------------------------------------------------------

            ViewBag.CargoPersonal = new SelectList(cargos);

            return View();
        }

        // POST: /Personal/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include="IDPersona,Nombre,ApellidoPaterno,ApellidoMaterno,DNI,FechaNacimiento,Direccion,Telefono,TipoPersona,CargoPersonal,FechaRegistro,Estado,IDTerminal,Email,Celular,IDUnidadVenta")] Personal personal)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            string activo = estados[0].valor;
            var dni_qry = from p in db.Persona
                          where p.Estado == activo && p.TipoPersona == tipo_persona_personal.valor
                          select p.DNI;
            string dni_tmp = personal.DNI;
            String error = null;

            //Verificar que sea mayor de edad
            if (personal.FechaNacimiento != null && 
                (DateTime.Now.Year - personal.FechaNacimiento.Value.Year < 18 || 
                (DateTime.Now.Year - personal.FechaNacimiento.Value.Year == 18 && DateTime.Now.Month < personal.FechaNacimiento.Value.Month) ||
                (DateTime.Now.Year - personal.FechaNacimiento.Value.Year == 18 && DateTime.Now.Month == personal.FechaNacimiento.Value.Month && DateTime.Now.Day < personal.FechaNacimiento.Value.Day)))
            {
                error = "El personal debe ser mayor de edad";
            }
            else if (dni_qry.Contains(dni_tmp))
            {
                error += "El D.N.I. " + personal.DNI + " ya está registrado";
            }
            else
            {
                personal.TipoPersona = tipo_persona_personal.valor;
                personal.FechaRegistro = DateTime.Now;
                if (ModelState.IsValid)
                {
                    Persona persona = new Persona();
                    persona.IDPersona = personal.IDPersona;
                    persona.Nombre = personal.Nombre;
                    persona.ApellidoPaterno = personal.ApellidoPaterno;
                    persona.ApellidoMaterno = personal.ApellidoMaterno;
                    persona.DNI = personal.DNI;
                    persona.FechaNacimiento = personal.FechaNacimiento;
                    persona.Direccion = personal.Direccion;
                    persona.Telefono = personal.Telefono;
                    persona.Celular = personal.Celular;
                    persona.Email = personal.Email;
                    persona.CargoPersonal = personal.CargoPersonal;
                    persona.Estado = personal.Estado;
                    persona.IDTerminal = personal.IDTerminal;
                    persona.Terminal = personal.Terminal;
                    persona.IDUnidadVenta = personal.IDUnidadVenta;
                    persona.UnidadVenta = personal.UnidadVenta;
                    persona.TipoPersona = personal.TipoPersona;
                    persona.FechaRegistro = personal.FechaRegistro;
                    persona.Incidente = personal.Incidente;
                    persona.OrdenCompra = personal.OrdenCompra;
                    persona.OrdenMantenimiento = personal.OrdenMantenimiento;
                    persona.Pasaje = personal.Pasaje;
                    persona.Usuario = personal.Usuario;
                    persona.ProgramacionViaje_x_Personal = personal.ProgramacionViaje_x_Personal;
                    persona.Reserva = personal.Reserva;
                    persona.Producto_x_Proveedor = personal.Producto_x_Proveedor;
                    persona.conCuenta = false;
                    db.Persona.Add(persona);
                    try
                    {
                        db.SaveChanges();
                    }
                    catch
                    {
                        TempData["create_failure"] = "el personal no se pudo registrar";
                        return RedirectToAction("Index");
                    }
                    TempData["create_success"] = "el personal se registró exitosamente";
                    return RedirectToAction("Index");
                }
            }

            ViewBag.Estado = new SelectList(estados, "valor", "nombre", personal.Estado);

            //Controlar global vs. local-----------------------------------------------------------
            if (!global)
            {
                //Usuario local
                ViewBag.IDTerminal = (int)Session["IDTerminal"];
            }
            else
            {
                //Usuario global
                var terminales = from t in db.Terminal
                                 where t.Estado == activo
                                 select t;
                int id_terminal = (int)Session["IDTerminal"];
                ViewBag.IDTerminal = new SelectList(terminales, "IDTerminal", "Nombre", id_terminal);
                var unidades_venta = from u in db.UnidadVenta
                                     where u.Estado == activo
                                     select u;
                ViewBag.IDUnidadVenta = new SelectList(unidades_venta, "IDUnidadVenta", "Nombre");
            }
            //-------------------------------------------------------------------------------------

            ViewBag.CargoPersonal = new SelectList(cargos, personal.CargoPersonal);

            TempData["create_failure"] = error;

            return View(personal);
        }

        // GET: /Personal/Edit/5
        public ActionResult Edit(int? id)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            if (id == null)
            {
                return View("Error404");
            }
            try
            {
                Persona persona = db.Persona.Find(id);
                if (persona == null)
                {
                    return View("Error404");
                }

                //No permitir acceso a info de otras terminales
                if (!global && persona.IDTerminal != (int)Session["IDTerminal"])
                {
                    TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                    return RedirectToAction("Index", "ModuloAdmin");
                }

                Personal personal = new Personal();
                personal.IDPersona = persona.IDPersona;
                personal.Nombre = persona.Nombre;
                personal.ApellidoPaterno = persona.ApellidoPaterno;
                personal.ApellidoMaterno = persona.ApellidoMaterno;
                personal.DNI = persona.DNI;
                personal.FechaNacimiento = persona.FechaNacimiento;
                personal.Direccion = persona.Direccion;
                personal.Telefono = persona.Telefono;
                personal.Celular = persona.Celular;
                personal.Email = persona.Email;
                personal.CargoPersonal = persona.CargoPersonal;
                personal.Estado = persona.Estado;
                personal.IDTerminal = persona.IDTerminal;
                personal.Terminal = persona.Terminal;
                personal.IDUnidadVenta = persona.IDUnidadVenta;
                personal.UnidadVenta = persona.UnidadVenta;
                personal.TipoPersona = persona.TipoPersona;
                personal.FechaRegistro = persona.FechaRegistro;
                personal.Incidente = persona.Incidente;
                personal.OrdenCompra = persona.OrdenCompra;
                personal.OrdenMantenimiento = persona.OrdenMantenimiento;
                personal.Pasaje = persona.Pasaje;
                personal.Usuario = persona.Usuario;
                personal.ProgramacionViaje_x_Personal = persona.ProgramacionViaje_x_Personal;
                personal.Reserva = persona.Reserva;
                personal.Producto_x_Proveedor = persona.Producto_x_Proveedor;

                ViewBag.Estado = new SelectList(estados, "valor", "nombre", personal.Estado);

                //Controlar global vs. local-----------------------------------------------------------
                if (!global)
                {
                    //Usuario local
                    ViewBag.IDTerminal = (int)Session["IDTerminal"];
                }
                else
                {
                    //Usuario global
                    string activo = estados[0].valor;
                    var terminales = from t in db.Terminal
                                     where t.Estado == activo
                                     select t;
                    int id_terminal = (int)Session["IDTerminal"];
                    ViewBag.IDTerminal = new SelectList(terminales, "IDTerminal", "Nombre", id_terminal);
                    var unidades_venta = from u in db.UnidadVenta
                                         where u.Estado == activo
                                         select u;
                    ViewBag.IDUnidadVenta = new SelectList(unidades_venta, "IDUnidadVenta", "Nombre");
                }
                //-------------------------------------------------------------------------------------

                ViewBag.CargoPersonal = new SelectList(cargos, personal.CargoPersonal);

                return View(personal);
            }
            catch
            {
                TempData["edit_failure"] = "no se encontró el personal";
                return RedirectToAction("Index");
            }
        }

        // POST: /Personal/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="IDPersona,Nombre,ApellidoPaterno,ApellidoMaterno,DNI,FechaNacimiento,Direccion,Telefono,TipoPersona,CargoPersonal,PuntosAcumulados,FechaRegistro,Estado,IDTerminal,Email,Celular,IDUnidadVenta")] Personal personal)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            if (ModelState.IsValid)
            {
                Persona persona = new Persona();
                persona.IDPersona = personal.IDPersona;
                persona.Nombre = personal.Nombre;
                persona.ApellidoPaterno = personal.ApellidoPaterno;
                persona.ApellidoMaterno = personal.ApellidoMaterno;
                persona.DNI = personal.DNI;
                persona.FechaNacimiento = personal.FechaNacimiento;
                persona.Direccion = personal.Direccion;
                persona.Telefono = personal.Telefono;
                persona.Celular = personal.Celular;
                persona.Email = personal.Email;
                persona.CargoPersonal = personal.CargoPersonal;
                persona.Estado = personal.Estado;
                persona.IDTerminal = personal.IDTerminal;
                persona.Terminal = personal.Terminal;
                persona.IDUnidadVenta = personal.IDUnidadVenta;
                persona.UnidadVenta = personal.UnidadVenta;
                persona.TipoPersona = personal.TipoPersona;
                persona.FechaRegistro = personal.FechaRegistro;
                persona.Incidente = personal.Incidente;
                persona.OrdenCompra = personal.OrdenCompra;
                persona.OrdenMantenimiento = personal.OrdenMantenimiento;
                persona.Pasaje = personal.Pasaje;
                persona.Usuario = personal.Usuario;
                persona.ProgramacionViaje_x_Personal = personal.ProgramacionViaje_x_Personal;
                persona.Reserva = personal.Reserva;
                persona.Producto_x_Proveedor = personal.Producto_x_Proveedor;
                db.Entry(persona).State = EntityState.Modified;
                try
                {
                    db.SaveChanges();
                }
                catch
                {
                    TempData["edit_failure"] = "el personal no se pudo modificar";
                    return RedirectToAction("Index");
                }
                TempData["edit_success"] = "el personal se modificó exitosamente";
                return RedirectToAction("Index");
            }

            ViewBag.Estado = new SelectList(estados, "valor", "nombre", personal.Estado);

            //Controlar global vs. local-----------------------------------------------------------
            if (!global)
            {
                //Usuario local
                ViewBag.IDTerminal = (int)Session["IDTerminal"];
            }
            else
            {
                //Usuario global
                string activo = estados[0].valor;
                var terminales = from t in db.Terminal
                                 where t.Estado == activo
                                 select t;
                int id_terminal = (int)Session["IDTerminal"];
                ViewBag.IDTerminal = new SelectList(terminales, "IDTerminal", "Nombre", id_terminal);
                var unidades_venta = from u in db.UnidadVenta
                                     where u.Estado == activo
                                     select u;
                ViewBag.IDUnidadVenta = new SelectList(unidades_venta, "IDUnidadVenta", "Nombre");
            }
            //-------------------------------------------------------------------------------------

            ViewBag.CargoPersonal = new SelectList(cargos, personal.CargoPersonal);

            return View(personal);
        }

        // GET: /Personal/Delete/5
        public ActionResult Delete(int? id)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            if (id == null)
            {
                return View("Error404");
            }
            try
            {
                Persona persona = db.Persona.Find(id);
                if (persona == null)
                {
                    return View("Error404");
                }

                //No permitir acceso a info de otras terminales
                if (!global && persona.IDTerminal != (int)Session["IDTerminal"])
                {
                    TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                    return RedirectToAction("Index", "ModuloAdmin");
                }

                try
                {
                    ViewBag.Estado = estados.Find(e => e.valor == persona.Estado).nombre;
                }
                catch
                {
                    TempData["details_failure"] = "no se encontró el estado del personal";
                }

                return View(persona);
            }
            catch
            {
                TempData["delete_failure"] = "no se encontró el personal";
                return RedirectToAction("Index");
            }
        }

        // POST: /Personal/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            ActionResult result_seguridad = ValidarSeguridad();
            if (result_seguridad != null)
            {
                return result_seguridad;
            }
            bool global = PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.GLOBAL);
            ViewBag.Global = global;

            Persona persona = db.Persona.Find(id);
            persona.Estado = est_anulado.valor;
            db.Entry(persona).State = EntityState.Modified;
            try
            {
                db.SaveChanges();
            }
            catch
            {
                TempData["delete_failure"] = "el personal no se pudo eliminar";
                return RedirectToAction("Index");
            }
            TempData["delete_success"] = "el personal se eliminó exitosamente";
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private ActionResult ValidarSeguridad()
        {

            if (Session["Permisos"] == null)
            {
                TempData["LogueatePrimero"] = SystemField.NO_LOGUEADO;
                return RedirectToAction("Index", "ValidarLogin");
            }
            //ESTOY LOGUEADO PERO NO TENGO PERMISO PARA REALIZAR ESTA ACCION
            if (!PerfilsController.TienePermiso((int)Session["Permisos"], PerfilsController.ADMINISTRACION))
            {
                TempData["SinPermiso"] = SystemField.SIN_PERMISO;
                return RedirectToAction("Index", "MainPageEmployes");
            }
            return null;
        }
    }
}
